home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / zugabe / va45 / visual45 / library / wrkspace / workspa.s < prev   
Text File  |  1998-08-14  |  13KB  |  446 lines

  1.   IFD GWVA_WSP_CTE_WORKSPACE
  2.  
  3.     IFND GWVA_WSP_CTE_TYPICAL_NB_BLOC
  4. GWVA_WSP_CTE_TYPICAL_NB_BLOC=0
  5.     ENDC
  6.   
  7. GWVA_WPS_COPY_AUTOSIZE=0
  8.     text
  9.     rsreset
  10. GWVA_WSP_WORKSPACE_NEXT:    rs.l    1   ;!!!!! cf. _GWVA_VAR_WORKSPACE_FIRST
  11. GWVA_WSP_WORKSPACE_SIZE:    rs.l    1   ; en octets ! total, header compris
  12. GWVA_WSP_WORKSPACE_BLOCS:    rs.l    0
  13. _GWVA_WSP_WORKSPACE_STRUCT_LENGTH:    rs.l    0
  14.  
  15.     rsreset
  16. GWVA_WSP_FREEBLOC_NEXT:        rs.l    1   ;!!!!! cf. _GWVA_VAR_BLOC_FIRST_FREE
  17. GWVA_WSP_FREEBLOC_SIZE:        rs.l    1   ; en nombre de longs effectivement allouables (disponibles) a un usedbloc.
  18. GWVA_WSP_FREEBLOC_BEGIN:    rs.l    0
  19. _GWVA_WSP_FREEBLOC_STRUCT_LENGTH:    rs.l    0
  20.  
  21.     rsreset
  22. GWVA_WSP_USEDBLOC_SIZE:        rs.l    1   ; en nombre de longs disponibles dans le bloc, hors header
  23. GWVA_WSP_USEDBLOC_BEGIN:    rs.l    0
  24. _GWVA_WSP_USEDBLOC_STRUCT_LENGTH:    rs.l    0
  25.  
  26. ;************************************************
  27. ;* Method name : -
  28. ;* Asm label   : GWVA_WSP_MORE_WORKSPACE
  29. ;* Description : Mallocs an area to add to the workspace
  30. ;*
  31. ;* in  : GWVA_WSP_CTE_WORKSPACE : size of workspace : 
  32. ;*    if GWVA_WSP_CTE_TYPICAL_NB_BLOC=0 or not defined
  33. ;*    then =total size of workspace (in byte)
  34. ;*    else =typical (max) size of one bloc 
  35. ;* in  : GWVA_WSP_CTE_TYPICAL_NB_BLOC : number of blocs to be used in this workspace (optionnal)
  36. ;*    NB: does not need to be the exact number of blocs ; it's a hint given 
  37. ;*    to the algorithme so that it reserves memory for blocs informations.
  38. ;*    If less blocs are effectivly used, there will be more memory usable for blocs ; 
  39. ;*    if more blocs are effectivly used, there will be less memory usable for blocs ;
  40. ;*    if the exact number of bloc is used, the amount of memory needed is garanteed.
  41. ;*    0 is a special value (cf. GWVA_WSP_CTE_WORKSPACE).
  42. ;*
  43. ;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
  44. ;*
  45. ;* 07/98 : Création
  46. ;************************************************
  47. GWVA_WSP_MORE_WORKSPACE:
  48.     move.l    #GWVA_WSP_CTE_WORKSPACE,d0
  49.     move.l    #GWVA_WSP_CTE_TYPICAL_NB_BLOC,d1
  50.     tst.l    d0
  51.     beq.s    .fin_erreur
  52.     tst.l    d1
  53.     beq.s    .deja_calc
  54.  
  55.     add.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH,d0
  56.     mulu.l    d1,d0
  57. .deja_calc:
  58.     move.l    d0,-(sp)
  59.     add.l    #_GWVA_WSP_WORKSPACE_STRUCT_LENGTH,d0
  60.     MXALLOC    d0
  61.     IFNE DEBUG
  62.       move.l    a6,d0
  63.     ENDC
  64.     tst.l    d0
  65.     beq.s    .malloc_erreur
  66.     addq.l    #3,d0
  67.     andi.l    #~3,d0
  68.     move.l    d0,a0
  69.     move.l    (sp)+,d0
  70.  
  71.     ; on doit chercher l'endroit ou inserer ce workspace (a0) dans la file
  72.     ; ie: le bloc actuel (a1) est avant le nouveau et le suivant est apres
  73.     lea    _GWVA_VAR_WORKSPACE_FIRST,a2
  74. .pas_encore:
  75.     movea.l    a2,a1
  76.     move.l    GWVA_WSP_WORKSPACE_NEXT(a1),a2    ; next=last first
  77.     tst.l    a2
  78.     beq.s    .fin_de_liste        ; deja fini ?
  79.     cmpa.l    a0,a2
  80.     bmi.s    .pas_encore
  81.  
  82. .trouve:
  83. .fin_de_liste:
  84.     move.l    GWVA_WSP_WORKSPACE_NEXT(a1),GWVA_WSP_WORKSPACE_NEXT(a0)
  85.     move.l    a0,GWVA_WSP_WORKSPACE_NEXT(a1)
  86.     move.l    d0,GWVA_WSP_WORKSPACE_SIZE(a0)
  87.  
  88. .build_workspace:
  89.     lea    GWVA_WSP_WORKSPACE_BLOCS(a0),a0
  90.     ; informe ce workspace avec un faux usedbloc dont la taille est correcte
  91.     sub.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH,d0
  92.     lsr.l    #2,d0            ; en nombre de longs
  93.     move.l    d0,GWVA_WSP_USEDBLOC_SIZE(a0)    ; size = d0
  94.     ; libere ce faux usedbloc
  95.     lea    GWVA_WSP_USEDBLOC_BEGIN(a0),a0
  96.     bsr    GWVA_WSP_FREE_BLOC
  97. .fin_ok:
  98.     clr.w    d7
  99.     rts
  100.     
  101. .malloc_erreur:
  102.     move.l    (sp)+,d0
  103. .fin_erreur:
  104.     ; retourne une erreur
  105.     move.w    #GWVA_ERROR_GENERIC,d7
  106.     rts
  107.     
  108. ;************************************************
  109. ;* Method name : -
  110. ;* Asm label   : GWVA_WSP_NEW_BLOC
  111. ;* Description : Gets one bloc of specified size (size is rounded up to long)
  112. ;*
  113. ;* in  : d0.l = size of the bloc in bytes
  114. ;*
  115. ;* out : a0.l-> bloc
  116. ;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
  117. ;*
  118. ;* 07/98 : Création
  119. ;************************************************
  120. GWVA_WSP_NEW_BLOC:
  121.     tst.l    d0
  122.     beq.s    .fin_erreur
  123.     
  124.     moveq.l    #3,d1
  125.     and.l    d0,d1
  126.     sne.b    d1
  127.     neg.b    d1
  128.     lsr.l    #2,d0    ; en nbre de longs
  129.     add.l    d1,d0
  130.  
  131.     lea    _GWVA_VAR_FREEBLOC_FIRST,a0
  132.     
  133. .get_next_free_bloc:
  134.     move.l    GWVA_WSP_FREEBLOC_NEXT(a0),d1
  135.     beq.s    .fin_erreur
  136.     movea.l    a0,a1    ; garde le précédent pour faire lien
  137.     movea.l    d1,a0
  138.     cmp.l    GWVA_WSP_FREEBLOC_SIZE(a0),d0
  139.     beq.s    .get_the_free_bloc
  140.     bgt.s    .get_next_free_bloc
  141.  
  142.     ; ici (a0) on donc un bloc de bonne taille et on va couper dedans
  143.     lea    _GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0,d0.l*4),a2    ; nouveau debut du bloc libre
  144.  
  145.     move.l    GWVA_WSP_FREEBLOC_NEXT(a0),GWVA_WSP_FREEBLOC_NEXT(a2)
  146.     move.l    GWVA_WSP_FREEBLOC_SIZE(a0),d1
  147.     sub.l    d0,d1
  148.     sub.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1    ; dans l'usedbloc
  149.     beq.s    .get_the_free_bloc_all
  150.     move.l    d1,GWVA_WSP_FREEBLOC_SIZE(a2)
  151.     move.l    a2,GWVA_WSP_FREEBLOC_NEXT(a1)
  152.     move.l    d0,(a0)+        ; !!!!! GWVA_WSP_USEDBLOC_BEGIN
  153. .fin_ok:
  154.     clr.w    d7
  155.     rts
  156.     
  157. .fin_erreur:
  158.     move.w    #GWVA_ERROC_GENERIC,d7
  159.     rts
  160.  
  161. .get_the_free_bloc_all:
  162.     move.l    GWVA_WSP_FREEBLOC_SIZE(a0),d0
  163. .get_the_free_bloc:
  164.     move.l    GWVA_WSP_FREEBLOC_NEXT(a0),GWVA_WSP_FREEBLOC_NEXT(a1)
  165.     move.l    GWVA_WSP_FREEBLOC_SIZE(a0),GWVA_WSP_USEDBLOC_SIZE(a0)
  166.     move.l    d0,(a0)+        ; !!!!! GWVA_WSP_USEDBLOC_BEGIN
  167.     bra.s    .fin_ok
  168.     
  169. ;************************************************
  170. ;* Method name : -
  171. ;* Asm label   : GWVA_WSP_FREE_BLOC
  172. ;* Description : Frees the pointed bloc
  173. ;*
  174. ;* in  : a0.l-> bloc
  175. ;*
  176. ;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
  177. ;*
  178. ;* 07/98 : Création
  179. ;************************************************
  180. GWVA_WSP_FREE_BLOC:
  181.     move.l    #_GWVA_VAR_FREEBLOC_FIRST,d1
  182.     lea    -GWVA_WSP_USEDBLOC_BEGIN(a0),a0    ; pointe sur la structure
  183.     
  184. .get_next_free_bloc:
  185.     movea.l    d1,a1
  186.     move.l    GWVA_WSP_FREEBLOC_NEXT(a1),d1
  187.     beq.s    .yen_a_pas    ; dans le cas ou il n'y en a aucun
  188.     cmp.l    a0,d1
  189.     blt.s    .get_next_free_bloc
  190.     ; ici a1 pointe un freebloc qui est avant
  191.     ; et le freebloc suivant est apres
  192.  
  193.     sub.l    a1,d1    ; distance entre les deux freeblocs
  194.     sub.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH*2,d1    ; 1 dans le freebloc et 1 dans l'usedbloc
  195.     lsr.l    #2,d1
  196.     sub.l    GWVA_WSP_FREEBLOC_SIZE(a1),d1
  197.     cmp.l    GWVA_WSP_USEDBLOC_SIZE(a0),d1
  198.     beq.s    .juste_entre
  199.     
  200.     ; teste si l'usedbloc est collé juste apres le freebloc actuel
  201.     move.l    GWVA_WSP_FREEBLOC_SIZE(a1),d1
  202.     lea    GWVA_WSP_USEDBLOC_BEGIN(a1,d1.l*4),a2
  203.     cmp.l    a2,a0
  204.     bne    .ca_colle_pas_apres
  205.     
  206.     move.l    GWVA_WSP_USEDBLOC_SIZE(a0),d1
  207.     add.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1
  208.     add.l    d1,GWVA_WSP_FREEBLOC_SIZE(a1)
  209. .fin_ok:
  210.     clr.w    d7
  211.     rts
  212.     
  213. .ca_colle_pas_apres:
  214.     ; teste si l'usedbloc est collé juste avant le freebloc suivant
  215.     move.l    GWVA_WSP_USEDBLOC_SIZE(a0),d1
  216.     lea    _GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0,d1.l*4),a2
  217.     move.l    GWVA_WSP_FREEBLOC_NEXT(a1),d1
  218.     cmp.l    a2,d1
  219.     bne.s    .ca_colle_pas_avant_non_plus
  220.  
  221.     move.l    GWVA_WSP_FREEBLOC_NEXT(a1),a2
  222.     move.l    a0,GWVA_WSP_FREEBLOC_NEXT(a1)
  223.     move.l    GWVA_WSP_USEDBLOC_SIZE(a0),d1
  224.     add.l    GWVA_WSP_FREEBLOC_SIZE(a2),d1
  225.     add.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1
  226.     move.l    d1,GWVA_WSP_FREEBLOC_SIZE(a0)
  227.     move.l    GWVA_WSP_FREEBLOC_NEXT(a2),GWVA_WSP_FREEBLOC_NEXT(a0)
  228.     bra.s    .fin_ok
  229.     
  230. .yen_a_pas:
  231. .ca_colle_pas_avant_non_plus:
  232.     ; donc le bloc a liberer est isole entre deux usedblocs
  233.     move.l    GWVA_WSP_USEDBLOC_SIZE(a0),GWVA_WSP_FREEBLOC_SIZE(a0)
  234.     move.l    GWVA_WSP_FREEBLOC_NEXT(a1),GWVA_WSP_FREEBLOC_NEXT(a0)
  235.     move.l    a0,GWVA_WSP_FREEBLOC_NEXT(a1)
  236.     bra.s    .fin_ok
  237.  
  238. .juste_entre:
  239.     ; cas particulier : l'usedbloc est juste collé entre deux freeblocs
  240.     move.l    GWVA_WSP_FREEBLOC_NEXT(a1),a2
  241.     move.l    GWVA_WSP_FREEBLOC_NEXT(a2),GWVA_WSP_FREEBLOC_NEXT(a1)
  242.     move.l    GWVA_WSP_USEDBLOC_SIZE(a0),d1
  243.     add.l    GWVA_WSP_FREEBLOC_SIZE(a1),d1
  244.     add.l    GWVA_WSP_FREEBLOC_SIZE(a2),d1
  245.     add.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH*2/4,d1 ; 1 pour l'used bloc et 1 pour le freebloc suivant
  246.     move.l    d1,GWVA_WSP_FREEBLOC_SIZE(a1)
  247.     bra.s    .fin_ok
  248.  
  249. .fin_erreur:
  250.     move.w    #GWVA_ERROC_GENERIC,d7
  251.     rts
  252.     
  253. ;************************************************
  254. ;* Method name : -
  255. ;* Asm label   : GWVA_WSP_SHRINK_BLOC
  256. ;* Description : Shrinks the pointed bloc so its size is reduced to the specified size
  257. ;*
  258. ;* Rq : content of the bloc remains unchanged
  259. ;*
  260. ;* in  : a0.l-> bloc
  261. ;* in  : d0.l = new size (<= old size) (bytes)
  262. ;*
  263. ;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
  264. ;*
  265. ;* 07/98 : Création
  266. ;************************************************
  267. GWVA_WSP_SHRINK_BLOC:
  268.     tst.l    d0
  269.     beq.s    .free
  270.     
  271.     moveq.l    #3,d1
  272.     and.l    d0,d1
  273.     sne.b    d1
  274.     neg.b    d1
  275.     lsr.l    #2,d0    ; en nbre de longs
  276.     add.l    d1,d0
  277.  
  278.     move.l    GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0),d1
  279.     sub.l    d0,d1
  280.     bmi.s    .fin_erreur
  281.     
  282.     sub.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1    ; dans l'usedbloc
  283.     ble.s    .pas_shrink_finalement
  284.  
  285.     move.l    d0,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0)
  286.     lea    _GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0,d0.l*4),a0
  287.     move.l    d1,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0)
  288. .free:
  289.     bra    GWVA_WSP_FREE_BLOC
  290.     
  291. .pas_shrink_finalement:
  292.     clr.w    d7
  293.     rts
  294.  
  295. .fin_erreur:
  296.     move.w    #GWVA_ERROC_GENERIC,d7
  297.     rts
  298.     
  299. ;************************************************
  300. ;* Method name : -
  301. ;* Asm label   : 
  302. ;* Description : Shrinks the pointed bloc so it begins at specified address (size reduced)
  303. ;*
  304. ;* Rq : content of the bloc remains unchanged
  305. ;*
  306. ;* in  : a0.l-> bloc
  307. ;* in  : a1.l-> new begining of the bloc ( a0.l <= a1.l < a0.l+bloc size )
  308. ;*
  309. ;* out : a1.l-> new begining of the bloc rounded down to long !!! USE THIS ONE
  310. ;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
  311. ;*
  312. ;* 07/98 : Création
  313. ;************************************************
  314. GWVA_WSP_SHRINKUP_BLOC:
  315.     move.l    a1,d0
  316.     andi.w    #~3,d0
  317.     move.l    d0,a1
  318.     sub.l    a0,d0    ; taille du freebloc
  319.     bmi.s    .fin_erreur
  320.     
  321.     lsr.l    #2,d0
  322.     
  323.     move.l    GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0),d1
  324.  
  325.     sub.l    d0,d1
  326.     beq.s    .free
  327.     bmi.s    .fin_erreur
  328.  
  329.     sub.l    #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d0    ; dans le freebloc
  330.     ble.s    .pas_shrink_finalement
  331.     
  332.     move.l    d0,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0)
  333.     move.l    d1,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a1)
  334.  
  335. .free:
  336.     bra    GWVA_WSP_FREE_BLOC
  337.     
  338. .pas_shrink_finalement:
  339.     clr.w    d7
  340.     rts
  341.     
  342. .fin_erreur:
  343.     move.w    #GWVA_ERROC_GENERIC,d7
  344.     rts
  345.     
  346. ;************************************************
  347. ;* Method name : -
  348. ;* Asm label   : GWVA_WSP_BLOC_MAX_SIZE_INQUIRE
  349. ;* Description : Inquires maximum bloc size
  350. ;*
  351. ;* out : d0.l = size in byte
  352. ;*
  353. ;* 07/98 : Création
  354. ;************************************************
  355. GWVA_WSP_BLOC_MAX_SIZE_INQUIRE:
  356.     lea    _GWVA_VAR_FREEBLOC_FIRST,a0
  357.     clr.l    d0    ; max=0 pour commencer
  358. .suivant:    
  359.     move.l    GWVA_WSP_FREEBLOC_NEXT(a0),d1
  360.     beq.s    .dernier
  361.     move.l    d1,a0
  362.     move.l    GWVA_WSP_FREEBLOC_SIZE(a0),d1
  363.     cmp.l    d1,d0
  364.     bge.s    .suivant    ; pas mieux
  365.     move.l    d1,d0
  366.     bra.s    .suivant
  367. .dernier:
  368.     lsl.l    #2,d0    ; -> en octets
  369.     rts
  370.     
  371. ;************************************************
  372. ;* Method name : -
  373. ;* Asm label   : GWVA_WSP_BLOC_SIZE_INQUIRE
  374. ;* Description : Inquires the usedbloc size
  375. ;*
  376. ;* in  : a0.l-> usedbloc
  377. ;*
  378. ;* out : d0.l = size
  379. ;*
  380. ;* 07/98 : Création
  381. ;************************************************
  382. GWVA_WSP_BLOC_SIZE_INQUIRE:
  383.     move.l    GWVA_WSP_USEDBLOC_SIZE-GWVA_WSP_USEDBLOC_BEGIN(a0),d0
  384.     rts
  385.     
  386.  
  387. ;************************************************
  388. ;* Method name : -
  389. ;* Asm label   : GWVA_WSP_BCOPY
  390. ;* Description : Copy datas
  391. ;*
  392. ;* Rq : saves d1-d7/a2-a7 ; a0-a1 are modified
  393. ;*
  394. ;* in  : a0.l-> source
  395. ;* in  : a1.l-> destination
  396. ;* in  : d0.l = number of bytes (rounded up to long) 
  397. ;*    or d0.l = GWVA_WPS_COPY_AUTOSIZE : autosize (copy all the source taking care of destination size)
  398. ;*
  399. ;* out : d0.l = size effectively copied
  400. ;*
  401. ;* 07/98 : Création
  402. ;************************************************
  403. GWVA_WSP_BCOPY:
  404.     move.l    d1,-(sp)
  405.     tst.l    d0
  406.     beq.s    .autosize
  407.     
  408.     moveq.l    #3,d1
  409.     and.l    d0,d1
  410.     sne.b    d1
  411.     neg.b    d1
  412.     lsr.l    #2,d0    ; en nbre de longs
  413.     add.l    d1,d0
  414.     move.l    d0,d1
  415.     bra.s    .size_ok
  416. .autosize:
  417.     move.l    GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0),d0
  418.     move.l    GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a1),d1
  419.     cmp.l    d1,d0
  420.     bgt.s    .size_inv
  421.     move.l    d0,d1
  422. .size_inv:
  423.     move.l    d1,d0
  424. .size_ok:
  425.     subq.l    #1,d1
  426. .bcl:
  427.     move.l    (a0)+,(a1)+
  428.     dbra    d1,.bcl
  429.     
  430. .fin_ok:
  431.     lsl.l    #2,d0
  432.     move.l    (sp)+,d1
  433.     rts
  434.     
  435.     data
  436.  
  437. _GWVA_VAR_WORKSPACE_FIRST:    dcb.b    _GWVA_WSP_WORKSPACE_STRUCT_LENGTH
  438.                 ;!!!!! les routines s'attendent a trouver ici une structure
  439.                 ; de workspace pour chercher _NEXT seulement
  440. _GWVA_VAR_FREEBLOC_FIRST:    dcb.b    _GWVA_WSP_FREEBLOC_STRUCT_LENGTH
  441.             ;!!!!! les routines s'attendent a trouver ici une structure
  442.             ; de bloc pour chercher _NEXT seulement
  443.     
  444.     bss
  445.     ENDC
  446.